import java.time.Instant;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.StructuredTaskScope;
import java.util.concurrent.TimeoutException;
import java.util.function.Supplier;

/**
 * 关闭策略
 *
 * @author Junki
 * @date 2023-11-14 11:00:16
 */
public class Demo03 {

    <T> List<T> runAll(List<Callable<T>> tasks) throws InterruptedException, ExecutionException {
        // ShutdownOnFailure 如果其中任何一个子任务失败，则关闭
        try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
            List<? extends Supplier<T>> suppliers = tasks.stream().map(scope::fork).toList();
            scope.join()
                    .throwIfFailed();  // 如果任何子任务失败，则传播异常
            return suppliers.stream().map(Supplier::get).toList();
        }
    }

    <T> T race(List<Callable<T>> tasks, Instant deadline) throws InterruptedException, ExecutionException, TimeoutException {
        // ShutdownOnSuccess 如果其中任何一个子任务成功，则关闭
        try (var scope = new StructuredTaskScope.ShutdownOnSuccess<T>()) {
            for (var task : tasks) {
                scope.fork(task);
            }
            return scope.joinUntil(deadline)
                    .result();  // 获取第一个完成的结果
        }
    }

}
